#include "meshTypes_fwd.hpp"
#include "structMeshOverlap.hpp"
#include <array>

using namespace hms;

bool operator==( const OverlapSegment& a, const OverlapSegment b ){
	return
		a.rank   == b.rank &&
		a.size   == b.size &&
		a.beg    == b.beg  &&
		a.ownBeg == b.ownBeg;
}

std::array<Array2Xi, 6> sizesAndOffsets(){
	std::array<Array2Xi, 6> sizesAndOffs;
	for ( Array2Xi& a : sizesAndOffs )
		a.resize(2, 12);

	/* see load_balancing.ods sheet #5 */
	sizesAndOffs[0] << // mesh size 0
		4, 4, 4, 5,   4, 4, 4, 5,   4, 4, 4, 5,
		4, 4, 4, 4,   4, 4, 4, 4,   5, 5, 5, 5;

	sizesAndOffs[1] << // mesh size stage 1
		5, 4, 4, 4,   3, 4, 6, 4,   4, 3, 4, 6,
		5, 5, 5, 5,   2, 2, 2, 2,   6, 6, 6, 6;
	
	sizesAndOffs[2] << // mesh size stage 2
		5, 4, 4, 4,   3, 4, 5, 5,   4, 3, 4, 6,
		5, 5, 5, 5,   3, 3, 3, 3,   5, 5, 5, 5;
	
	sizesAndOffs[3] << // offset 0
		0, 4, 8, 12,   0, 4, 8, 12,   0, 4, 8, 12,
		0, 0, 0,  0,   4, 4, 4,  4,   8, 8, 8,  8;
	
	sizesAndOffs[4] << // offset stage 1
		0, 5, 9, 13,   0, 3, 7, 13,   0, 4, 7, 11,
		0, 0, 0,  0,   5, 5, 5,  5,   7, 7, 7,  7;
	
	sizesAndOffs[5] << // offset stage 2
		0, 5, 9, 13,   0, 3, 7, 12,   0, 4, 7, 11,
		0, 0, 0,  0,   5, 5, 5,  5,   8, 8, 8,  8;
	
	return sizesAndOffs;
}

std::array<Array2Xi, 6> sizesAndOffsetsForTrueStructMesh(){
	std::array<Array2Xi, 6> sizesAndOffs;
	for( Array2Xi& a : sizesAndOffs) a.resize(2,4);

		sizesAndOffs[0] <<
		3, 3,   3, 3,
		3, 3,   4, 4;

		sizesAndOffs[1] <<
		3, 3,   4, 2,
		4, 4,   3, 3;

		sizesAndOffs[2] <<
		2, 4,   4, 2,
		2, 2,   5, 5;

		sizesAndOffs[3] <<
		0, 3,   0, 3,
		0, 0,   3, 3;

		sizesAndOffs[4] <<
		0, 3,   0, 4,
		0, 0,   4, 4;

		sizesAndOffs[5] <<
		0, 2,   0, 4,
		0, 0,   2, 2;

	return sizesAndOffs;	
}

std::array<Array2Xi, 6> sizesAndOffsetsForTrueRectMesh(){
	std::array<Array2Xi, 6> sizesAndOffs;
	for( Array2Xi& a : sizesAndOffs) a.resize(2,4);

	sizesAndOffs[0] <<
		5, 5,   5, 5,
		5, 5,   5, 5;

	sizesAndOffs[1] <<
	  6, 4,   4, 6,
		6, 6,   4, 4;

	sizesAndOffs[2] <<
	  3, 7,   7, 3,
		4, 4,   6, 6;

	sizesAndOffs[3] <<
		0, 5, 0, 5,
		0, 0, 5, 5;

	sizesAndOffs[4] <<
		0, 6, 0, 4,
		0, 0, 6, 6;

	sizesAndOffs[5] <<
		0, 3, 0, 7,
		0, 0, 4, 4;

	return sizesAndOffs;
}